package com.cashmama.market.api.domain.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cashmama.market.api.domain.service.ApiUserCenterService;
import com.cashmama.market.api.domain.vo.UserBaseInfo;
import com.cashmama.market.api.domain.vo.UserLoginInfo;
import com.cashmama.market.api.domain.vo.user.CashmamaQuotaVO;
import com.cashmama.market.api.domain.vo.user.UserBriefDTO;
import com.cashmama.market.api.infras.config.ApolloConfigUtil;
import com.cashmama.market.api.infras.exception.ApplicationException;
import com.cashmama.market.api.infras.utils.StringUtils;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.xjd.user.client.*;
import com.fqgj.xjd.user.client.enums.FrozenCodeEnum;
import com.fqgj.xjd.user.client.enums.PanStatusEnum;
import com.fqgj.xjd.user.client.enums.UserKycStatusEnum;
import com.fqgj.xjd.user.client.enums.UserQuotaEnum;
import com.fqgj.xjd.user.client.request.*;
import com.fqgj.xjd.user.client.response.*;
import com.google.common.collect.Lists;
import com.qianli.common.enums.BusinessTypeENUM;
import com.qianli.user.enums.UserAuthStatusEnum;
import com.qianli.user.facade.auth.UserAuthServiceFacade;
import com.qianli.user.ro.auth.UserAuthStatusRO;
import com.qianli.user.ro.query.UserBaseQueryRO;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Created with IntelliJ IDEA.
 * User: yujianfu (mr.vencnet@gmail.com)
 * Date: 2019-11-25
 * Time: 14:40
 */
@Service
public class UserIntegrationServiceImpl implements ApiUserCenterService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserIntegrationServiceImpl.class);

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserEmailService userEmailService;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private UserPanService userPanService;
    @Autowired
    private UserKycDocumentService userKycDocumentService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserFrozenService userFrozenService;
    @Autowired
    private ApolloConfigUtil apolloConfigUtil;
    @Autowired
    private UserQuotaService userQuotaService;
    @Autowired
    private UserAadhaarService userAadhaarService;
    @Autowired
    private UserContactService userContactService;
    @Autowired
    private UserAuthServiceFacade userAuthServiceFacade;
    @Autowired
    private UserBehaviorService userBehaviorService;

    @Override
    public UserLoginInfo getUserLoginInfoByToken(String token) {
        Response<com.fqgj.xjd.user.client.response.UserLoginInfo> userLoginInfoByToken = userService.getUserLoginInfoByToken(token);
        if(!userLoginInfoByToken.isSuccess() || userLoginInfoByToken.getData() == null){
            return null;
        }
        UserLoginInfo userLoginInfo = new UserLoginInfo();
        BeanUtils.copyProperties(userLoginInfoByToken.getData(), userLoginInfo);
        return userLoginInfo;
    }

    @Override
    public UserBaseInfo getUserBaseInfoByUserCode(String userCode) {
        Response<UserInfo> userInfoResponse = userInfoService.getUserInfoByUserCode(userCode);
        if(!userInfoResponse.isSuccess() || userInfoResponse.getData() == null){
            return null;
        }
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setMobile(userInfoResponse.getData().getUser().getMobile());
        userBaseInfo.setUserCode(userCode);
        return userBaseInfo;
    }

    @Override
    public UserWork getUserWorkInfoByUserCode(String userCode) {
        Response<UserInfo> userInfoResponse = userInfoService.getUserInfoByUserCode(userCode);
        if(!userInfoResponse.isSuccess() || userInfoResponse.getData() == null){
            return null;
        }
        return userInfoResponse.getData().getUserWork();
    }

    @Override
    public UserBriefDTO getUserBriefInfoByUserCode(String userCode) {
        UserInfo userInfo = userInfoService.getUserInfoByUserCode(userCode).getData();
        UserAuthEmail userAuthEmail = userEmailService.getUserEmail(userCode).getData();
        String name = (StringUtils.isEmpty(userInfo.getUserBase().getFirstName()) ? "" : userInfo.getUserBase().getFirstName())
                + (StringUtils.isEmpty(userInfo.getUserBase().getMiddleName()) ? "" : userInfo.getUserBase().getMiddleName())
                + (StringUtils.isEmpty(userInfo.getUserBase().getLastName()) ? "" : userInfo.getUserBase().getLastName());
        UserBriefDTO userBriefDTO = new UserBriefDTO();
        userBriefDTO.setName(name)
                .setMobile(userInfo.getUser().getMobile())
                .setEmail(userAuthEmail.getEmail());
        return userBriefDTO;
    }

    @Override
    public boolean pinCodeAndBirthdayStatus(String userCode) {
        UserInfo userInfo = Optional.ofNullable(userInfoService.getUserInfoByUserCode(userCode))
                .filter(Response::isSuccess).map(Response::getData).orElseGet(UserInfo::new);
        String birthday = Optional.ofNullable(userInfo.getUserBase()).orElseGet(UserBase::new).getBirthday();
        String pinCode = Optional.ofNullable(userInfo.getUserResident()).orElseGet(UserResident::new).getPinCode();
        return StringUtils.isNotEmpty(birthday) && StringUtils.isNotEmpty(pinCode);
    }

    @Override
    public boolean bindUserDevice(UserAccess userAccess) {
        if (null == userAccess.getUserAppInfo() || StringUtils.isEmpty(userAccess.getUserAppInfo().getGuestId())) {
            return false;
        }
        Response<UserDevice> response = userDeviceService.getDeviceByUserCodeAndGuestId(userAccess.getUserCode(), userAccess.getUserAppInfo().getGuestId());
        UserDevice userDevice = response.getData();
        if (null == userDevice) {
            UserDevice guestDevice = new UserDevice()
                    .setUserCode(userAccess.getUserCode())
                    .setGuestId(userAccess.getUserAppInfo().getGuestId())
                    .setClientId(userAccess.getUserAppInfo().getClientId())
                    .setPlatform(userAccess.getUserAppInfo().getPlatform().getType())
                    .setVersion(userAccess.getUserAppInfo().getVersion());
            Response<Boolean> booleanResponse = userDeviceService.addNewDevice(guestDevice);
            if (booleanResponse.isSuccess() && booleanResponse.getData()) {
                return true;
            }else{
                return false;
            }
        }
        return true;
    }

    @Override
    public PanStatusEnum panActionComplete(String userCode) {
        Response<UserPanInfo> userPanResponse = userPanService.getByUserCode(userCode);
        if (userPanResponse == null || !userPanResponse.isSuccess() || userPanResponse.getData() == null) {
            return null;
        }
        UserPanInfo userPanInfo = userPanResponse.getData();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(userPanInfo.getUserCode())
                && org.apache.commons.lang3.StringUtils.isNotBlank(userPanInfo.getCardNo())
                && org.apache.commons.lang3.StringUtils.isNotBlank(userPanInfo.getCardUrl())) {
            return PanStatusEnum.getEnumByStatus(userPanInfo.getPanStatus());
        } else if (PanStatusEnum.RE_UPLOAD.getStatus().equals(userPanInfo.getPanStatus())) {
            return PanStatusEnum.RE_UPLOAD;
        }
        return null;
    }

    @Override
    public UserKycStatusEnum kycActionComplete(String userCode) {
        List<UserKycDocumentInfo> infos = Optional.ofNullable(userKycDocumentService.getByUserCode(userCode))
                .filter(Response::isSuccess).map(Response::getData).orElse(Lists.newArrayList());
        if (CollectionUtils.isEmpty(infos)) {
            return null;
        }
        // 需要重新编辑
        long reEditNum = infos.stream()
                .filter(userKycDocumentInfo -> UserKycStatusEnum.RE_UPLOAD.equals(userKycDocumentInfo.getStatus())).count();
        if (reEditNum > 0) {
            return UserKycStatusEnum.RE_UPLOAD;
        }
        // 资料未填写
        long notFillNum = infos.stream()
                .filter(userKycDocumentInfo -> UserKycStatusEnum.INIT.equals(userKycDocumentInfo.getStatus())).count();
        if (notFillNum > 0) {
            return UserKycStatusEnum.INIT;
        }
        // 认证失败
        long authFailedNum = infos.stream()
                .filter(userKycDocumentInfo -> UserKycStatusEnum.CHECK_FAIL.equals(userKycDocumentInfo.getStatus())).count();
        if (authFailedNum > 0) {
            return UserKycStatusEnum.CHECK_FAIL;
        }
        // 认证成功
        long authSuccessNum = infos.stream()
                .filter(userKycDocumentInfo -> UserKycStatusEnum.CHECK_SUCCESS.equals(userKycDocumentInfo.getStatus())).count();
        if (authSuccessNum > 0) {
            return UserKycStatusEnum.CHECK_SUCCESS;
        }
        return null;
    }

    @Override
    public Boolean checkUserFreezeByFrozenCodeEnum(String userCode, String categoryCode, FrozenCodeEnum frozenCodeEnum) {
        Response<List<UserFrozen>> response = userFrozenService.getFrozenCodeByUserCode(userCode);
        List<UserFrozen> frozenList = response.getData();
        if (CollectionUtils.isNotEmpty(frozenList)) {
            for (UserFrozen userFrozen : frozenList) {
                if (userFrozen.getCode().equals(frozenCodeEnum.getCode())
                        && DateUtil.diffDateToSecond(userFrozen.getFrozenEndDate(), new Date()) >= 0
                        && userFrozen.getCategoryCode().equals(categoryCode)) {
                    return true;
                }
            }
        }
        return false;
    }


    @Override
    public String getUserFrozenDate(String userCode, FrozenCodeEnum frozenCodeEnum) {
        Response<User> userResponse = userService.getUserByUserCode(userCode);
        User user = userResponse.getData();
        if (user != null && CollectionUtils.isNotEmpty(user.getFrozenList())) {
            for (UserFrozen userFrozen : user.getFrozenList()) {
                if (userFrozen.getCode().equals(frozenCodeEnum.getCode())
                        && DateUtil.diffDateToSecond(userFrozen.getFrozenEndDate(), new Date()) >= 0) {
                    return DateUtil.getDate(userFrozen.getFrozenEndDate());
                }
            }
        }
        return null;
    }

    @Override
    public void initializationQuota(String userCode) {
        Integer initRiskLevel = apolloConfigUtil.getInitializationRiskLevel();
        //根据级别 产品 获取 额度
        UserQuotaRequest userQuotaRequest = new UserQuotaRequest();
        userQuotaRequest.setAmount(20000D);
        userQuotaRequest.setCategoryCode(null);
        userQuotaRequest.setUserCode(userCode);
        userQuotaRequest.setQuotaEnum(UserQuotaEnum.PASS);
        userQuotaRequest.setRiskLevel(initRiskLevel);
        userQuotaRequest.setDealNo("");
        Response<Boolean> response = userQuotaService.saveQuotaResult(userQuotaRequest);
        LOGGER.info("===设置默认额度===request:{}response:{}", JSON.toJSONString(userQuotaRequest), JSON.toJSONString(response));
    }

    private CashmamaQuotaVO isCashmamaUser(String mobile, String userCode){
        Response<UserAccessInfo> response = userService.getUserAccessInfoByMobile(mobile, "5");
        if(response.isSuccess() && response.getData() != null){
            UserBaseQueryRO userBaseQueryRO = new UserBaseQueryRO();
            userBaseQueryRO.setAppCode("5");
            userBaseQueryRO.setBiz(BusinessTypeENUM.XJD.getCode());
            userBaseQueryRO.setUserCode(userCode);
            Response<UserAuthStatusRO> userAuthStatusROResponse = userAuthServiceFacade.queryUserAuthStatus(userBaseQueryRO);
            if(userAuthStatusROResponse.getData() != null && userAuthStatusROResponse.getData().getIsOldUser() == UserAuthStatusEnum.SUCCESS.getCode()){
                CashmamaQuotaVO cashmamaQuotaVO = new CashmamaQuotaVO();
                cashmamaQuotaVO.setRiskLevel(4);
                cashmamaQuotaVO.setQuota(10000D);
                return cashmamaQuotaVO;
            }
        }
        return null;
    }

    @Override
    public void initializationQuota(String userCode, int riskLevel) {
        Response<UserQuotaResponse> quotaResponse = userQuotaService.getQuota(userCode, null);
        Integer existRiskLevel = Optional.ofNullable(quotaResponse)
                .filter(Response::isSuccess)
                .map(Response::getData)
                .map(UserQuotaResponse::getRiskLevel)
                .orElse(2);
        if(quotaResponse.getData() != null && existRiskLevel == riskLevel){
            return;
        }
        UserQuotaRequest userQuotaRequest = new UserQuotaRequest();
        userQuotaRequest.setAmount(20000D);
        userQuotaRequest.setCategoryCode(null);
        userQuotaRequest.setUserCode(userCode);
        userQuotaRequest.setQuotaEnum(UserQuotaEnum.PASS);
        userQuotaRequest.setRiskLevel(riskLevel);
        userQuotaRequest.setDealNo("");
        Response<Boolean> response = userQuotaService.saveQuotaResult(userQuotaRequest);
        LOGGER.info("===设置cashmama额度, userCode:{}, riskLevel:{} response:{}===", userCode, riskLevel, JSONObject.toJSONString(response));
    }

    @Override
    public List<UserQuotaResponse> getUserQuotaList(List<String> userCodes) {
        Response<List<UserQuotaResponse>> response = userQuotaService.selectQuotaByUserCodes(userCodes);
        if(!response.isSuccess()){
            throw new ApplicationException(response.getMsg());
        }
        return response.getData();
    }

    @Override
    public Boolean advanceAadhaarActionComplete(String userCode) {
        Response<UserAdvanceAadhaarVo> userAdvanceAadhaarVoResponse = userAadhaarService.getUserAdvanceAadhaar(userCode);
        if (userAdvanceAadhaarVoResponse == null || !userAdvanceAadhaarVoResponse.isSuccess()
                || userAdvanceAadhaarVoResponse.getData() == null) {
            return false;
        }
        UserAdvanceAadhaarVo userAdvanceAadhaarVo = userAdvanceAadhaarVoResponse.getData();
        return userAdvanceAadhaarVo.getStatus() == 2;
    }

    @Override
    public UserAdvanceAadhaarVo getUserAdvanceAadhaar(String userCode) {
        if (com.fqgj.common.utils.StringUtils.isEmpty(userCode)) {
            return null;
        }
        Response<UserAdvanceAadhaarVo> response = userAadhaarService.getUserAdvanceAadhaar(userCode);
        if (response == null || !response.isSuccess()) {
            LOGGER.error("查询失败,userCode:{}", userCode);
            throw new ApplicationException("Query failed");
        }
        return response.getData();
    }

    @Override
    public boolean auditRejectFreeze(User user, String productCategory) {
        if (com.fqgj.common.utils.CollectionUtils.isNotEmpty(user.getFrozenList())) {
            for (UserFrozen userFrozen : user.getFrozenList()) {
                if ((FrozenCodeEnum.BORROW_REJECT.getCode().equals(userFrozen.getCode()) || FrozenCodeEnum.REPAYMENT_OVERDUE.getCode().equals(userFrozen.getCode()))
                        && DateUtil.diffDateToSecond(userFrozen.getFrozenEndDate(), new Date()) > 0
                        && userFrozen.getCategoryCode().equals(productCategory)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void saveUserContactInfo(UserContact userContact, UserSocialContact userSocialContact, String appCode) {
        Response<Boolean> result = userContactService.addUserDeviceContact(userContact.getUserCode(), userSocialContact.getDeviceContact(), appCode);
        if (!result.isSuccess()) {
            LOGGER.error("查询失败,result:{}", result);
            throw new ApplicationException(result.getCode(), result.getMsg());
        }
    }

    @Override
    public void saveUserContactInfo(String userCode, String deviceContactUrl, String smsUrl, String appCode) {
        Response<Boolean> result = userContactService.addUserSmsInfo(userCode, deviceContactUrl, smsUrl, appCode);
        if (!result.isSuccess()) {
            LOGGER.error("查询失败,result:{}", result);
            throw new ApplicationException(result.getCode(), result.getMsg());
        }
    }

    @Override
    public void updateSmsInfo(String userCode, String smsUrl) {
        Response<Boolean> response = userContactService.updateUserDeviceContact(userCode, "", smsUrl);
        if(!response.isSuccess()){
            LOGGER.error("查询失败,result:{}", response);
            throw new ApplicationException(response.getCode(), response.getMsg());
        }
    }

    @Override
    public Boolean emailComplete(String userCode) {
        Response<UserAuthEmail> emailRsp = userEmailService.getUserEmail(userCode);
        return emailRsp != null && emailRsp.isSuccess() && emailRsp.getData() != null && StringUtils.isNotEmpty(emailRsp.getData().getEmail());
    }

    @Override
    public boolean isCreditComplete(String userCode) {
        UserQuotaResponse userQuotaResponse = userQuotaService.getQuota(userCode, null).getData();
        if (userQuotaResponse == null || userQuotaResponse.getRiskLevel() == null) {
            return false;
        }
        return true;
    }

    @Override
    public boolean isCreditCompleteByUserCode(String userCode) {
        UserQuotaResponse userQuotaResponse = userQuotaService.getQuota(userCode, null).getData();
        if (userQuotaResponse == null || userQuotaResponse.getRiskLevel() == null) {
            return false;
        }
        return true;
    }

    @Override
    public boolean isFirstRiskReject(String userCode) {
        if(StringUtils.isEmpty(userCode)){
            return false;
        }
        UserBaseQueryRO userBaseQueryRO = new UserBaseQueryRO();
        userBaseQueryRO.setAppCode("5");
        userBaseQueryRO.setBiz(BusinessTypeENUM.XJD.getCode());
        userBaseQueryRO.setUserCode(userCode);
        Response<UserAuthStatusRO> response = userAuthServiceFacade.queryUserAuthStatus(userBaseQueryRO);
        if(response.getData() != null && response.getData().getFirstRoundRiskStatus() == UserAuthStatusEnum.REJECT.getCode()){
            return true;
        }
        return false;
    }

    @Override
    public boolean isNewUser(String userCode) {

        return false;
    }

    @Override
    public UserContactAddressBook getUserContactInfo(String userCode) {
        Response<UserContactAddressBook> result = userContactService.getUserDeviceContactByUserCode(userCode);
        if(!result.isSuccess()){
            LOGGER.error("查询失败,result:{}", result);
            throw new ApplicationException(result.getCode(), result.getMsg());
        }
        return result.getData();
    }

    @Override
    public List<UserPanInfo> getUserPanInfoList(String panCardNo) {
        Response<List<UserPanInfo>> result = userPanService.getListByPanNo(panCardNo);
        if(!result.isSuccess()){
            LOGGER.error("查询失败,result:{}", result);
            throw new ApplicationException(result.getMsg());
        }
        return result.getData();
    }

    @Override
    public UserPanInfo getUserPanInfo(String userCode) {
        Response<UserPanInfo> result = userPanService.getByUserCode(userCode);
        if(!result.isSuccess()){
            throw new ApplicationException(result.getMsg());
        }
        return result.getData();
    }

    @Override
    public void saveOpenBlackHistory(UserOpenBlackListRequest request) {
        Response<Boolean> response = userBehaviorService.saveUserOpenBlack(request);
    }
}
